using System;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.ComponentModel;


namespace WebComponents.Templates
{
    #region DisplayState class
    [DefaultProperty("Title"),
        ToolboxData("<{0}:DisplayStats runat=server></{0}:DisplayStats>"),
        Designer("WebComponents.Templates.Design.DisplayStatsDesigner")]

    public class DisplayStats : System.Web.UI.WebControls.WebControl, INamingContainer
    {
        #region Private Member Variables
        private StatsData statsData = null;
        private ITemplate statsTemplate = null;
        #endregion

        #region Properties
        [Bindable(true),
            Category("Appearance"),
            DefaultValue("Site Statistics")]
        public string Title
        {
            get
            {
                object o = ViewState["DisplayStateTitle"];
                if (o == null)
                    return "Site Statistics";	// return the default value
                else
                    return (string)o;
            }

            set
            {
                ViewState["DisplayStateTitle"] = value;
            }
        }

        [Bindable(true),
        Category("Appearance"),
        DefaultValue("0")]
        public int TotalPostCount
        {
            get
            {
                object o = ViewState["DisplayStateTotalPostCount"];
                if (o == null)
                    return 0;	// return the default value
                else
                    return (int)o;
            }

            set
            {
                if (value < 0)
                    throw new ArgumentException("The total number of posts cannot be less than zero.");
                else
                    ViewState["DisplayStateTotalPostCount"] = value;
            }
        }

        [Bindable(true),
        Category("Appearance"),
        DefaultValue("0")]
        public int TotalUserCount
        {
            get
            {
                object o = ViewState["DisplayStateTotalUserCount"];
                if (o == null)
                    return 0;	// return the default value
                else
                    return (int)o;
            }

            set
            {
                if (value < 0)
                    throw new ArgumentException("The total number of users cannot be less than zero.");
                else
                    ViewState["DisplayStateTotalUserCount"] = value;
            }
        }


        [
        Browsable(true),
        DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)
        ]
        public StatsData StatsData
        {
            get
            {
                this.EnsureChildControls();
                return statsData;
            }
        }

        [
        Browsable(false),
        DefaultValue(null),
        Description("The statistics template."),
        TemplateContainer(typeof(StatsData)),
        PersistenceMode(PersistenceMode.InnerDefaultProperty),
        TemplateInstance(TemplateInstance.Single)
        ]
        public virtual ITemplate StatsTemplate
        {
            get
            {
                return statsTemplate;
            }
            set
            {
                statsTemplate = value;
            }
        }

        // For composite controls, the Controls collection needs to be overriden to
        // ensure that the child controls have been created before the Controls
        // property can be modified by the page developer...
        public override ControlCollection Controls
        {
            get
            {
                this.EnsureChildControls();
                return base.Controls;
            }
        }
        #endregion

        #region Internal Design Helper Methods
        // This internal helper method is used by the designer to set the StatsData instance
        // to a specified StatsData.  Note that the public StatsData property is read-only...
        internal void AddStatsData(StatsData sd)
        {
            this.statsData = sd;
        }
        #endregion

        #region Overridden Control Members
        protected override void CreateChildControls()
        {
            Controls.Clear();		// clear out the control hierarchy

            // create a new StatsData instance based on the property values
            this.statsData = new StatsData(this.Title, this.TotalPostCount, this.TotalUserCount);

            // get the template
            ITemplate template = this.StatsTemplate;
            if (template == null)
                // the user has not specified a template, we need to generate a default template
                template = new DefaultStatsTemplate();

            // instantiate the StatsData in the template
            template.InstantiateIn(statsData);
            Controls.Add(statsData);		// add the StatsData to the control hierarchy
        }

        public override void DataBind()
        {
            // Create the child controls...
            CreateChildControls();
            this.ChildControlsCreated = true;		// mark that the children have been created			

            base.DataBind();		// call the DataBind method
        }
        #endregion
    }
    #endregion

    #region Default Stats Template class
    internal sealed class DefaultStatsTemplate : ITemplate
    {
        void ITemplate.InstantiateIn(Control container)
        {
            // Display the content as follows:
            //  <asp:Label ... />
            //	<br>Post Count: <asp:Label ... />
            //  <br>User Count: <asp:Label ... />
            // where the Label Web controls have the values of the appropriate
            // properties in the Container
            Label titleLabel = new Label();
            titleLabel.DataBinding += new EventHandler(titleLabel_DataBind);

            LiteralControl pcText = new LiteralControl("<br>Post Count: ");

            Label pcLabel = new Label();
            pcLabel.DataBinding += new EventHandler(pcLabel_DataBind);

            LiteralControl ucText = new LiteralControl("<br>User Count: ");

            Label ucLabel = new Label();
            ucLabel.DataBinding += new EventHandler(ucLabel_DataBind);

            // add the controls to the Container
            container.Controls.Add(titleLabel);
            container.Controls.Add(pcText);
            container.Controls.Add(pcLabel);
            container.Controls.Add(ucText);
            container.Controls.Add(ucLabel);
        }

        #region DataBind Event Handlers
        private void titleLabel_DataBind(object sender, EventArgs e)
        {
            // set the Text property of the Label to the TotalPostCount property
            Label titleLabel = (Label)sender;
            StatsData container = (StatsData)titleLabel.NamingContainer;
            titleLabel.Text = container.Title;
        }

        private void pcLabel_DataBind(object sender, EventArgs e)
        {
            // set the Text property of the Label to the TotalPostCount property
            Label pcLabel = (Label)sender;
            StatsData container = (StatsData)pcLabel.NamingContainer;
            pcLabel.Text = String.Format("{0:#,##0}", container.TotalPostCount);
        }

        private void ucLabel_DataBind(object sender, EventArgs e)
        {
            // set the Text property of the Label to the TotalUserCount property
            Label ucLabel = (Label)sender;
            StatsData container = (StatsData)ucLabel.NamingContainer;
            ucLabel.Text = String.Format("{0:#,##0}", container.TotalUserCount);
        }
        #endregion
    }
    #endregion
}
